#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#define PASSWORD "123"

int getch(void);
void gotoxy(int x, int y);
void password();
void menu();
void add();
void list();
void search();
void modify();
void delete();

int main() {
	system("clear");
	password();
	return 0;
}

void password() {
	gotoxy(22, 2);
	printf("Authorized Person Only\n\n");
	gotoxy(30, 4);
	printf("password: ");

	char pass[64] = {0};
	char ch = 0;
	int i = 0;

	while (ch != 10) { // 10 -> '\n'
		ch = getch();
		// printf("ch = %d\n", ch);
		if (ch != 10) {
			printf("%c", '*');
			pass[i] = ch;
			i++;
		}
	}
	pass[i] = '\0';

	if (strcmp(pass, PASSWORD) == 0) {
		gotoxy(30, 6);
		/* printf("\033[0;32mCORRECT PASSWORD\033[0m"); */
		menu();
	} else {
		gotoxy(30, 6);
		printf("\033[0;31mYou entered the wrong password\033[0m\n");
		sleep(1);
		system("clear");
		password();
	}
	printf("\n");
}

// x表示离左边多远，y表示离上边多远
void gotoxy(int x, int y) {
	printf("%c[%d;%df", 0x1B, y, x);
}

/* reads from keypress, doesn't echo */
int getch(void) {
    struct termios oldattr, newattr;
    int ch;
    tcgetattr( STDIN_FILENO, &oldattr );
    newattr = oldattr;
    newattr.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
    return ch;
}

void menu() {
	system("clear");
	while (1) {
		gotoxy(30, 1);
		printf("\n\n\t\tPHONEBOOK MENU");
		printf("\n\n\t\t1. Add New");
		printf("\n\n\t\t2. Search");
		printf("\n\n\t\t3. List");
		printf("\n\n\t\t4. Modify");
		printf("\n\n\t\t5. Delete");
		printf("\n\n\t\t6. Exit");

		printf("\n\n\t\tEnter your option: ");

		//getchar();
		int op = getchar();
		// printf("op = %c op = %d\n", op, op);
		getchar();

		switch (op) {
			case '1': 
				add();
				break;
			case '2': 
				search();
				break;
			case '3':
				list();
				break;
			case '4':
				modify();
				break;
			case '5':
				delete();
				break;
			case '6':
				exit(1);
			default:
				printf("Invalid option\n");
		}
	}
}

void add() {
	char name[100];
	char addr[100];
	char gender[10];
	char phone[20];

	system("clear");
	gotoxy(31, 4);
	printf("DB NEW SECTION\n");
	FILE *fp = fopen("db.txt", "ab+");
	if (fp == NULL) {
		fprintf(stderr, "Failed to create the required file.");
	} else {
		gotoxy(31, 6);
		printf("Name: \t");
		gotoxy(52, 6);
		fgets(name, sizeof(name), stdin);
		name[strlen(name)-1] = '\0';

		gotoxy(31, 7);
		printf("Address: \t");
		gotoxy(52, 7);
		fgets(addr, sizeof(addr), stdin);
		addr[strlen(addr)-1] = '\0';

		gotoxy(31, 8);
		printf("Gender: \t");
		gotoxy(52, 8);
		fgets(gender, sizeof(gender), stdin);
		gender[strlen(gender)-1] = '\0';

		gotoxy(31, 9);
		printf("Phone number: \t");
		gotoxy(52, 9);
		fgets(phone, sizeof(phone), stdin);
		phone[strlen(phone)-1] = '\0';

		// 多一个换行符以区分
		fprintf(fp, "%s %s %s %s\n", name, addr, gender, phone);
	}
	fclose(fp);
	system("clear");
	gotoxy(31, 4);
	printf("Do you want to add more data.Press y to contine:");
	fflush(stdin);
	int ch = getchar();
	getchar(); // get rid of \n
	if (ch == 'y' || ch == 'Y') {
		menu();
	} else {
		exit(1);
	}
}

void list() {
	char name[100];
	char addr[100];
	char gender[10];
	char phone[20];

	printf("\n\n\t\t\033[0;32mDB LIST SECTION OPENED\033[0m\n\n");
	FILE *fp = fopen("db.txt", "rb");

	while (fscanf(fp, "%s %s %s %s", name, addr, gender, phone) != EOF) {
		printf("\t\t--------------------------\n");
		printf("\t\tName: %s\n", name);
		printf("\t\tAddr: %s\n", addr);
		printf("\t\tGender: %s\n", gender);
		printf("\t\tPhone: %s\n", phone);
		printf("\t\t--------------------------\n");
	}
	fclose(fp);
	printf("\t\tEnter y|Y for menu section:");
	int ch = getchar();
	getchar(); // get rid of \n
	if (ch == 'y' || ch == 'Y') {
		menu();
	} else {
		exit(1);
	}
}

void search() {
	char name[100];
	char addr[100];
	char gender[10];
	char phone[20];
	char name1[100];
	int found = 0;

	// getchar();
	// fflush(stdin);
	system("clear");

	FILE *fp = fopen("db.txt", "rb");
	if (fp == NULL) {
		fprintf(stderr, "Failed to open file\n");
		exit(1);
	}
	printf("\n\n\t\tEnter the name of the person you want to see the detail: ");
	fgets(name1, sizeof(name1), stdin);
	if (name1[strlen(name1)-1] == '\n') {
		name1[strlen(name1)-1] = '\0';
	}

	while (fscanf(fp, "%s %s %s %s\n", name, addr, gender, phone) != EOF) {
		if (strcmp(name, name1) == 0) {
			found = 1;
			gotoxy(39, 4);
			printf("RECORD FOUND");
			gotoxy(28, 5);
			printf("----------------------------------");
			found = 1;
			gotoxy(31, 6);
			printf("Name: \t%s", name);
			gotoxy(31, 7);
			printf("Addr: \t%s", addr);
			gotoxy(31, 8);
			printf("Gender: \t%s", gender);
			gotoxy(31, 9);
			printf("Phone: \t%s", phone);
			gotoxy(31, 11);
			printf("----------------------------------");
			gotoxy(18, 12);
			printf("Enter y for menu option. ");

			int ch = getchar();
			getchar();
			if (ch == 'y' || ch == 'Y') {
				menu();
			} else {
				exit(1);
			}
		} 	
	}

	if (found == 0) {
		system("clear");
		gotoxy(39, 4);
		printf("No record found.");
		gotoxy(39, 6);
		printf("Enter a to enter name again or any key to open menu section:");
		int ch = getchar();
		getchar();
		system("clear");
		if (ch == 'a') {
			search();
		} 	
	}

	fclose(fp);
}

void modify() {
	char name[100];
	char addr[100];
	char gender[10];
	char phone[20];

	char new_addr[100];
	char new_gender[10];
	char new_phone[20];
	char name1[100];

	int found = 0;

	system("clear");

	FILE *fp1 = fopen("temp.txt", "ab");
	if (fp1 == NULL) {
		fprintf(stderr, "Failed to create temp.txt\n");
		exit(1);
	}

	FILE *fp = fopen("db.txt", "rb");
	if (fp == NULL) {
		fprintf(stderr, "Failed to open data.txt\n");
		exit(1);
	}

	printf("\n\n\t\tEnter the name to search: ");
	fgets(name1, sizeof(name1), stdin);
	if (name1[strlen(name1)-1]=='\n') {
		name1[strlen(name1)-1] = '\0';
	}
	while (fscanf(fp, "%s %s %s %s\n", name, addr, gender, phone) != EOF) {
		if (strcmp(name1, name) == 0) {
			found = 1;
			gotoxy(31, 4);
			printf("DB MODIFY SECTION OPENED");

			gotoxy(31, 6);
			printf("Enter the new address: ");
			scanf("%s", new_addr);
			
			gotoxy(31, 7);
			printf("Enter the new gender: ");
			scanf("%s", new_gender);

			gotoxy(31, 8);
			printf("Enter the new phone: ");
			scanf("%s", new_phone);

			fprintf(fp1,"%s %s %s %s\n", name, new_addr, new_gender, new_phone);
		} else {
			fprintf(fp1,"%s %s %s %s\n", name, addr, gender, phone);
		}		
	}

	if (found == 0) {
		printf("\n\n\t\tRecord not found\n");
		exit(1);
	}
	fclose(fp);
	fclose(fp1);

	FILE *fp2 = fopen("temp.txt", "rb");
	if (fp1 == NULL) {
		fprintf(stderr, "Failed to create temp.txt\n");
		exit(1);
	}

	// 先清空db.txt
	FILE *fp4 = fopen("db.txt", "wb");
	if (fp4 == NULL) {
		fprintf(stderr, "Failed to create temp.txt\n");
		exit(1);
	}
	fclose(fp4);

	FILE *fp3 = fopen("db.txt", "ab");
	if (fp == NULL) {
		fprintf(stderr, "Failed to open data.txt\n");
		exit(1);
	}

	// temp.txt -> db.txt
	while (fscanf(fp2, "%s %s %s %s\n", name, addr, gender, phone) != EOF) {
		fprintf(fp3, "%s %s %s %s\n", name, addr, gender, phone);
	}

	fclose(fp2);
	fclose(fp3);
	printf("\n\n\t\tPress y for menu option. ");
	fflush(stdin);
	getchar(); // get rid of '\n'
	int ch = getchar();
	getchar(); // get rid of '\n'
	if (ch == 'y' || ch == 'Y') {
		menu();
	} else {
		exit(1);
	}
}

void delete() {
	char name[100];
	char addr[100];
	char gender[10];
	char phone[20];
	char name1[100];

	int found = 0;

	system("clear");

	FILE *fp1 = fopen("temp2.txt", "ab");
	if (fp1 == NULL) {
		fprintf(stderr, "Failed to create temp.txt\n");
		exit(1);
	}

	FILE *fp = fopen("db.txt", "rb");
	if (fp == NULL) {
		fprintf(stderr, "Failed to open data.txt\n");
		exit(1);
	}

	printf("\n\n\t\tEnter the name to search: ");
	fgets(name1, sizeof(name1), stdin);
	if (name1[strlen(name1)-1]=='\n') {
		name1[strlen(name1)-1] = '\0';
	}
	while (fscanf(fp, "%s %s %s %s\n", name, addr, gender, phone) != EOF) {
		if (strcmp(name1, name) == 0) {
			found = 1;
			printf("\n\n\t\tRecord deleted successfully\n");
		} else {
			fprintf(fp1,"%s %s %s %s\n", name, addr, gender, phone);
		}		
	}

	if (found == 0) {
		printf("\n\n\t\tRecord not found\n");
		exit(1);
	}
	fclose(fp);
	fclose(fp1);

	FILE *fp2 = fopen("temp2.txt", "rb");
	if (fp1 == NULL) {
		fprintf(stderr, "Failed to create temp.txt\n");
		exit(1);
	}

	// 先清空db.txt
	FILE *fp4 = fopen("db.txt", "wb");
	if (fp4 == NULL) {
		fprintf(stderr, "Failed to create temp.txt\n");
		exit(1);
	}
	fclose(fp4);

	FILE *fp3 = fopen("db.txt", "ab");
	if (fp == NULL) {
		fprintf(stderr, "Failed to open data.txt\n");
		exit(1);
	}

	// temp.txt -> db.txt
	while (fscanf(fp2, "%s %s %s %s\n", name, addr, gender, phone) != EOF) {
		fprintf(fp3, "%s %s %s %s\n", name, addr, gender, phone);
	}

	fclose(fp2);
	fclose(fp3);

	printf("\n\n\t\tPress y for menu option. ");
	fflush(stdin);
	int ch = getchar();
	// printf("ch = %c ch = %d\n", ch, ch);
	getchar(); // get rid of '\n'
	if (ch == 'y' || ch == 'Y') {
		menu();
	} else {
		exit(1);
	}
}
